# -*- encoding: utf-8 -*-
"""
App级的共通的检测类的装饰器
"""

import hmac
import hashlib
import base64
import copy
from functools import wraps

from tornado import gen

from common import utiltool, timetool
from common import config as conf
import settings
from appinstance import mongo_mtd_pool


def check_sign(fn):
    """
    签名验证
    :param fn:
    :return:
    """
    def _check_sign(request_handler):
        if not settings.IS_CHECK_SIGN:
            return fn(request_handler)
        dicx = copy.deepcopy(request_handler.request.arguments)
        sign = dicx.pop('sign', None)
        try:
            # 把不参与签名的key移除
            for key in settings.IGNORE_SIGN_KEY_LIST:
                dicx.pop(key)
        except KeyError:
            pass
        try:
            public_key = settings.PUBLIC_KEY
        except KeyError:
            public_key = ''
        dict = sorted(dicx.iteritems(), key=lambda d: d[0])
        canshu = ""
        for (k, v) in dict:
            v_len = len(v)
            for i in range(v_len):
                canshu += '{0}{1}'.format(k, v[i])
        canshu = canshu[0:canshu.__len__()]
        signer = hmac.new(public_key, canshu, hashlib.sha1).digest()
        if sign == base64.b64encode(signer):
            return fn(request_handler)
        else:
            return utiltool.response_write(request_handler, {"code": "1001", "msg": conf.CODE1001})
    return _check_sign


def check_access_token(func):
    """
    检测用户本次的access_token是否有效
    :param func: request对象请求
    :return:{'code':'','msg':''}
    """
    @wraps(func)
    @gen.coroutine
    def check(*args, **kw):
        """
        """
        para_dict = args[0].request.arguments
        user_id = int(para_dict['user_id'][0])
        access_token = para_dict['access_token'][0]
        product_type = int(para_dict['product_type'][0])

        # collection = get_collection(settings.MONGO_DATA_DB, settings.MONGO_DEVICE_COLLECTION)
        collection = mongo_mtd_pool.get_collection(settings.MONGO_MTD_DBNAME, settings.MONGO_MTD_DEVICE_COLLECTION)
        result = yield collection.find_one(
            {'userid': user_id, 'accesstoken': access_token, 'producttype': product_type},
            {'_id': 0, 'ExpireDate': 1})
        if result:
            if result['ExpireDate'] >= timetool.get_timestamp():
                yield func(*args)
            else:
                if user_id in settings.WHITE_USER_ID_LIST:
                    yield func(*args)
                else:
                    utiltool.response_write(args[0], {"code": "1012", "msg": conf.CODE1012})
        else:
            if user_id in settings.WHITE_USER_ID_LIST:
                yield func(*args)
            else:
                utiltool.response_write(args[0], {"code": "1011",
                                                  "msg": conf.CODE1011})
    return check